home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
GL
/
libdemo
/
slider.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
9KB
|
439 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* Definitions for slider bar routines.
* These work with the event-handling routines.
* Written by Thant Tessman, modified a bit by Gavin Bell,
* for Silicon Graphics
*/
#include <stdio.h>
#include <gl.h>
#include <get.h>
#include <fmclient.h>
#include <device.h>
#include "slider.h"
#include "event.h"
typedef struct slider_struct
{
int type; /* SLIDER_INT or SLIDER_FLOAT */
long gid; /* Window I'm in */
long displaymode; /* And display mode */
sliderval *val; /* Current value */
float min, max; /* Minimum and maximum value */
float cornerx, cornery; /* Corner coordinates */
long wcornerx, wcornery; /* .. and in screen pixels */
long worx, wory; /* Origin of window we're in */
float sizex, sizey; /* Size */
long wsizex, wsizey; /* ... and in screen pixels */
fmfonthandle fh, fh2; /* Fonts from font manager */
float oldsize; /* Size of fh2 */
char title[64]; /* Storage for slider title */
int active; /* Being moved? */
void (*fn)(); /* Function to call when changes */
} Slider;
/*
* Local function prototypes
*/
static void activate_slider(Slider *);
static void deactivate_slider(Slider *);
static void slider_resize(Slider *);
static void adjust_slider(Slider *, int);
static void save_winstuff(void);
static void restore_winstuff(void);
static void image_slot(Slider *), image_knob(Slider *);
char *
add_slider(char *title, int type, float min, float max,
sliderval *variable, float cornerx, float cornery,
float sizex, float sizey, void (*fn)())
{
long gid;
Slider *me;
me = (Slider *) malloc(sizeof(Slider));
memset((char *)me, (char)0, sizeof(Slider));
me->type = type;
me->gid = gid = winget();
me->displaymode = getdisplaymode();
me->val = variable;
me->min = min; me->max = max;
me->active = FALSE;
strncpy(me->title, title, 64);
fminit();
me->fh = fmfindfont("Times-Roman");
me->cornerx = cornerx; me->cornery = cornery;
me->sizex = sizex; me->sizey = sizey;
me->fn = fn;
slider_resize(me);
if (!isqueued(LEFTMOUSE)) qdevice(LEFTMOUSE);
add_event(gid, LEFTMOUSE, DOWN, activate_slider, (char *)me);
add_event(gid, LEFTMOUSE, UP, deactivate_slider, (char *)me);
if (!isqueued(REDRAW)) qdevice(REDRAW);
add_event(ANY, REDRAW, gid, slider_resize, (char *)me);
add_event(gid, MOUSEX, ANY, adjust_slider, (char *)me);
return (char *)me;
}
void
draw_slider(char *t)
{
long oldgid;
char str[100];
float length;
Slider *s;
s = (Slider *)t;
save_winstuff();
oldgid = winget();
winset(s->gid);
viewport(s->wcornerx, s->wcornerx+s->wsizex-1,
s->wcornery, s->wcornery+s->wsizey-1);
fmsetfont(s->fh2);
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(50, 50, 50);
else
color(36);
clear();
ortho2(-0.2, 1.2, -1.0, 2.0);
switch (s->type)
{
case SLIDER_INT:
sprintf(str, s->title, (*s->val).i);
break;
case SLIDER_FLOAT:
sprintf(str, s->title, (*s->val).f);
break;
}
length = fmgetstrwidth(s->fh2, str);
length = length * 1.4 / s->wsizex / 2.0;
cmov2(0.5 - length, 1.0);
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(255, 255, 255);
else
color(7);
fmprstr(str);
image_slot(s);
switch (s->type)
{
case SLIDER_INT:
translate(((float)(*s->val).i - s->min)/
(s->max - s->min), 0.0, 0.0);
break;
case SLIDER_FLOAT:
translate(((*s->val).f - s->min)/
(s->max - s->min), 0.0, 0.0);
break;
}
scale(0.01, 0.3, 1.0);
image_knob(s);
winset(oldgid);
restore_winstuff();
}
static void
slider_resize(Slider *me)
{
long oldgid;
long sx, sy;
oldgid = winget();
winset(me->gid);
getorigin(&me->worx, &me->wory);
getsize(&sx, &sy);
me->wcornerx = sx*me->cornerx;
me->wcornery = sy*me->cornery;
/* This is written this way to avoid off-by-one errors */
me->wsizex = sx*(me->cornerx+me->sizex) - me->wcornerx;
me->wsizey = sy*(me->cornery+me->sizey) - me->wcornery;
{
float t;
t = (double) (me->wsizey) / 3.5;
if (me->fh2 == NULL || t != me->oldsize)
{
if (me->fh2 != NULL)
fmfreefont(me->fh2);
me->fh2 = fmscalefont(me->fh, t);
me->oldsize = t;
}
}
if (me->displaymode == DMDOUBLE || me->displaymode == DMRGBDOUBLE)
{
draw_slider((char *)me);
swapbuffers();
draw_slider((char *)me);
}
else
draw_slider((char *)me);
winset(oldgid);
}
static Boolean mousexqueued;
static void
activate_slider(Slider *s)
{
int x, mx, my;
x = getvaluator(MOUSEX);
mx = x - s->worx;
my = getvaluator(MOUSEY);
my = my - s->wory;
if (mx < s->wcornerx || mx > s->wcornerx+s->wsizex
|| my < s->wcornery || my > s->wcornery+s->wsizey)
return;
mousexqueued = isqueued(MOUSEX);
if (!mousexqueued)
{
qdevice(MOUSEX);
}
s->active = TRUE;
adjust_slider(s, x);
}
static void
deactivate_slider(Slider *s)
{
long prev_window;
if (s->active == FALSE) return;
prev_window = winget();
if (!mousexqueued)
{
unqdevice(MOUSEX);
}
winset(s->gid);
if (s->displaymode == DMDOUBLE || s->displaymode == DMRGBDOUBLE)
{
if (s->fn != NULL) s->fn(s);
draw_slider((char *)s);
swapbuffers();
if (s->fn != NULL) s->fn(s);
draw_slider((char *)s);
}
s->active = FALSE;
winset(prev_window);
}
static void
adjust_slider(Slider *s, int mx)
{
float oldval, newval;
long oldgid;
if (s->active == FALSE) return;
mx = mx - s->worx;
if (s->type == SLIDER_INT)
oldval = (float) (*s->val).i;
else oldval = (*s->val).f;
/* This scales from 0.0 to 1.0 */
newval = ((mx - s->wcornerx) * 1.4 / s->wsizex) - 0.2;
/* And this scales from min to max */
newval= s->min + newval*(s->max - s->min);
if (newval < s->min) newval = s->min;
if (newval > s->max) newval = s->max;
if (s->type == SLIDER_INT) newval = (float)((int)newval);
if (oldval != newval)
{
if (s->type == SLIDER_INT)
(*s->val).i = (int)newval;
else
(*s->val).f = newval;
oldgid = winget();
winset(s->gid);
if (s->fn != NULL) s->fn(s);
draw_slider((char *)s);
swapbuffers();
winset(oldgid);
}
}
/*
* This routine figures out what matrix mode we're in, and
* saves the relevant matrices. It then puts an identity matrix on
* top of the VIEWING or SINGLE stack, and also saves the viewport.
* When exiting, the matrix state will be in MVIEWING or MSINGLE
*/
static Matrix idmatrix =
{
1., 0., 0., 0.,
0., 1., 0., 0.,
0., 0., 1., 0.,
0., 0., 0., 1.,
};
static int lastmode;
static void
save_winstuff()
{
lastmode = getmmode();
if (lastmode == MSINGLE)
{
pushmatrix();
loadmatrix(idmatrix);
}
else
{
Matrix m;
mmode(MPROJECTION);
getmatrix(m);
mmode(MVIEWING);
pushmatrix(); /* Stack is: Viewing */
loadmatrix(m); /* ......... Projection */
pushmatrix(); /* ......... Identity */
loadmatrix(idmatrix);
}
pushviewport();
}
static void
restore_winstuff()
{
popviewport();
if (lastmode == MSINGLE)
{
popmatrix();
}
else
{
Matrix m;
popmatrix();
getmatrix(m); /* Projection matrix */
mmode(MPROJECTION);
loadmatrix(m);
mmode(MVIEWING);
popmatrix(); /* Viewing back */
mmode(lastmode); /* And put mode back */
}
}
static void
image_slot(Slider *s)
{
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(0, 0, 255);
else
color(4);
rectf(0.0, -0.2, 1.0, 0.2);
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(255, 255, 0);
else
color(3);
rect(0.0, -0.2, 1.0, 0.2);
}
static void
image_knob(Slider *s)
{
rotate(450, 'z');
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(240, 240, 240);
else
color(54);
pmv2i(-2, -2);
pdr2i(-1, -1);
pdr2i(-1, 1);
pdr2i(-2, 2);
pclos();
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(200, 200, 200);
else
color(51);
pmv2i(-2, 2);
pdr2i(-1, 1);
pdr2i(1, 1);
pdr2i(2, 2);
pclos();
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(150, 150, 150);
else
color(46);
pmv2i(2, 2);
pdr2i(1, 1);
pdr2i(1, -1);
pdr2i(2, -2);
pclos();
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(130, 130, 130);
else
color(44);
pmv2i(2, -2);
pdr2i(1, -1);
pdr2i(-1, -1);
pdr2i(-2, -2);
pclos();
if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
RGBcolor(170, 170, 170);
else
color(48);
rectfi(-1, -1, 1, 1);
}